package role

import (
	"fmt"
	"gitee.com/kudingc/role_proxy/common"
	"gitee.com/kudingc/role_proxy/models"
	"gitee.com/kudingc/role_proxy/service/util"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
)

// @Summary 新增角色并授权
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param body body models.AddRole true "角色与menu信息，不授权的话，不传MenuData字段即可"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/addRole [post]
func addRoleHandler(c *gin.Context) {
	var msg string
	var addRole models.AddRole
	var sysRoleMenu models.SysRoleMenu

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	c.BindJSON(&addRole)
	common.ZhLogger.Info(fmt.Sprintf("%d新增角色%s并授权%v", userId, addRole.RoleName, addRole.MenuData))

	state := models.StateOk
	if err := sysRoleMenu.AddRole(addRole, userId); err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "添加成功"
	}
	c.JSON(http.StatusOK, models.Res{
		State: state,
		Msg:   msg,
	})
}

// @Summary 修改角色及权限
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param body body models.UpdateRole true "角色与menu信息，如果不需要修改权限，不传MenuData字段即可"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/updateRole [post]
func updateRoleHandler(c *gin.Context) {
	var msg string
	var updateRole models.UpdateRole
	var sysRoleMenu models.SysRoleMenu

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	c.BindJSON(&updateRole)
	common.ZhLogger.Info(fmt.Sprintf("%d修改角色信息%v", userId, updateRole))

	state := models.StateOk
	if err := sysRoleMenu.UpdateRole(updateRole, userId); err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "添加成功"
	}
	c.JSON(http.StatusOK, models.Res{
		State: state,
		Msg:   msg,
	})
}

// @Summary 获取角色信息
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param roleId path int true "角色id"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/getRoleData/{roleId} [get]
func getRoleDataHandler(c *gin.Context) {
	var msg string
	var sysRoleMenu models.SysRoleMenu

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	state := models.StateOk
	roleId, err := strconv.Atoi(c.Param("roleId"))
	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
		c.JSON(http.StatusOK, models.Res{
			State: state,
			Msg:   msg,
		})
		return
	}
	common.ZhLogger.Info(fmt.Sprintf("%d获取角色%d的详细信息", userId, roleId))

	data, err := sysRoleMenu.GetRoleData(roleId)
	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "查询成功"
	}
	c.JSON(http.StatusOK, models.Res{
		State: state,
		Msg:   msg,
		Data:  data,
	})
}

// @Summary 获取角色信息
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/getRoleList [get]
func getRoleListHandler(c *gin.Context) {
	var msg string
	var sysRoleMenu models.SysRoleMenu

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	common.ZhLogger.Info(fmt.Sprintf("%d获取角色列表", userId))

	state := models.StateOk
	data, err := sysRoleMenu.GetRoleList()
	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "查询成功"
	}
	c.JSON(http.StatusOK, models.Res{
		State: state,
		Msg:   msg,
		Data:  data,
	})
}

// @Summary 修改用户与角色列表关联关系
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param body body models.UserRoles true "用户与角色id"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/updateUserRoles [post]
func updateUserRolesHandler(c *gin.Context) {
	var msg string
	var userRole models.UserRoles
	var sysUserRole models.SysUserRole

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	c.BindJSON(&userRole)
	common.ZhLogger.Info(fmt.Sprintf("%d修改用户%d与角色%s的对应关系", userId, userRole.UserId, userRole.RoleIds))

	state := models.StateOk
	if err := sysUserRole.UpdateUserRoles(userRole.UserId, userRole.RoleIds); err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "修改成功"
	}
	c.JSON(http.StatusOK, models.Res{
		State: state,
		Msg:   msg,
	})
}

// @Summary 修改角色与用户列表关联关系
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param body body models.RoleUsers true "角色与用户id"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/updateRoleUsers [post]
func updateRoleUsersHandler(c *gin.Context) {
	var msg string
	var userRole models.RoleUsers
	var sysUserRole models.SysUserRole

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	c.BindJSON(&userRole)
	common.ZhLogger.Info(fmt.Sprintf("%d修改角色%d与用户%s的对应关系", userId, userRole.RoleId, userRole.UserIds))

	state := models.StateOk
	if err := sysUserRole.UpdateRoleUsers(userRole.RoleId, userRole.UserIds); err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "修改成功"
	}
	c.JSON(http.StatusOK, models.Res{
		State: state,
		Msg:   msg,
	})
}

// @Summary 获取指定用户所拥有的角色列表
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param userId path int true "用户id"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/getUserRoles/{userId} [get]
func getUserRolesHandler(c *gin.Context) {
	var sysUserRole models.SysUserRole
	var msg string

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	state := models.StateOk
	reqUserId, err := strconv.Atoi(c.Param("userId"))

	common.ZhLogger.Info(fmt.Sprintf("%d获取指定用户%d所拥有的角色列表", userId, reqUserId))

	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
		c.JSON(http.StatusOK, models.Res{
			State: state,
			Msg:   msg,
		})
		return
	}
	roleData, err := sysUserRole.GetUserRoles(reqUserId)
	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "查询成功！"
	}
	c.JSON(http.StatusOK, models.Res{
		Msg:   msg,
		State: state,
		Data:  roleData,
	})
}

// @Summary 获取指定角色所拥有的用户列表
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param roleId path int true "角色id"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/getRoleUsers/{roleId} [get]
func getRoleUsersHandler(c *gin.Context) {
	var sysUserRole models.SysUserRole
	var msg string

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	state := models.StateOk
	roleId, err := strconv.Atoi(c.Param("roleId"))

	common.ZhLogger.Info(fmt.Sprintf("%d获取指定角色%d所拥有的用户列表", userId, roleId))

	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
		c.JSON(http.StatusOK, models.Res{
			State: state,
			Msg:   msg,
		})
		return
	}
	userData, err := sysUserRole.GetRoleUsers(roleId)
	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "查询成功！"
	}
	c.JSON(http.StatusOK, models.Res{
		Msg:   msg,
		State: state,
		Data:  userData,
	})
}

// @Summary 修改角色与菜单对应关系
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param body body models.RoleMenus true "角色与菜单id"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/updateRoleMenus [post]
func updateRoleMenusHandler(c *gin.Context) {
	var msg string
	var roleMenu models.RoleMenus
	var sysRoleMenu models.SysRoleMenu

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	c.BindJSON(&roleMenu)
	common.ZhLogger.Info(fmt.Sprintf("%d修改角色%d与菜单%v的对应关系", userId, roleMenu.RoleId, roleMenu.MenuData))

	state := models.StateOk
	if err := sysRoleMenu.UpdateRoleMenus(roleMenu.RoleId, roleMenu.MenuData); err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "修改成功"
	}
	c.JSON(http.StatusOK, models.Res{
		State: state,
		Msg:   msg,
	})
}

// @Summary 获取角色与菜单对应关系
// @Tags 权限相关
// @Produce json
// @Param Authorization header string true "token"
// @Param roleId path int true "角色id"
// @Success 200 {object} models.Res "成功"
// @Router /v1/role/getRoleMenus/{roleId} [get]
func getRoleMenusHandler(c *gin.Context) {
	var msg string
	var sysRoleMenu models.SysRoleMenu

	userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

	state := models.StateOk
	roleId, err := strconv.Atoi(c.Param("roleId"))
	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
		c.JSON(http.StatusOK, models.Res{
			State: state,
			Msg:   msg,
		})
		return
	}

	common.ZhLogger.Info(fmt.Sprintf("%d获取角色%s对应的菜单列表", userId, roleId))

	data, err := sysRoleMenu.GetRoleMenuDataList(roleId)
	if err != nil {
		state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
	} else {
		msg = "查询成功"
	}
	c.JSON(http.StatusOK, models.Res{
		State: state,
		Msg:   msg,
		Data:  data,
	})
}

// 自定义函数
func customFunctionHandler(apiData common.ApiData) gin.HandlerFunc {
	return func(c *gin.Context) {
		var msg string

		userId, _ := strconv.Atoi(c.Request.Header["User-Id"][0])

		// 解析参数
		for _, paramData := range apiData.Params {
			switch paramData.PathType {
			case common.BODY:
				c.BindJSON(&paramData.ParamValue)
			case common.PATH:
				paramData.ParamValue = c.Param(paramData.ParamName)
			case common.QUERY:
				paramData.ParamValue = c.Query(paramData.ParamName)
			}
		}

		state := models.StateOk
		data, err := apiData.F()
		if err != nil {
			state, msg = util.ErrHandle(err, c.Request.RequestURI, c.Request.Method, userId)
		} else {
			msg = "成功"
		}
		c.JSON(http.StatusOK, models.Res{
			State: state,
			Msg:   msg,
			Data:  data,
		})
	}
}
